using FreeSql.DataAnnotations;
using FreeSql.Internal.Model;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using OrmTestDomain;
using ShellProgressBar;
using Yitter.IdGenerator;

namespace FreeSqlTest.BackgroundServices;

public class FreeSqlLowCodeTestService(ILogger<FreeSqlDefaultTestService> logger, IFreeSql freeSql)
    : BackgroundService
{
    protected override Task ExecuteAsync(CancellationToken stoppingToken)
    {
        SingleSpiltCurd();
        return Task.CompletedTask;
    }

    private Dictionary<string, object> BuildDictionaryParam(object input)
    {
        var json = JsonConvert.SerializeObject(input);
        var dic = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
        return dic;
    }

    private IList<object> PrepareTestData(TableInfo table)
    {
        var dic = new List<Dictionary<string, object>>();
        var random = new Random();
        var randomNumber = random.Next(100, 200);
        var totalTicks = randomNumber;

        var progressBarOptions = new ProgressBarOptions { ProgressCharacter = '─', ProgressBarOnBottom = true };
        using (var bar = new ProgressBar(totalTicks, "Test Data Preparing....", progressBarOptions))
        {
            for (var i = 1; i <= totalTicks; i++)
            {
                dic.Add(BuildDictionaryParam(new
                        {
                            CreateTime = DateTime.Now.AddDays(1),
                            Id = YitIdHelper.NextId(),
                            RowVersion = YitIdHelper.NextId(),
                            Name = Guid.NewGuid().ToString()
                        })
                       );
                dic.Add(BuildDictionaryParam(new
                {
                    CreateTime = DateTime.Now.AddDays(-2),
                    Id = YitIdHelper.NextId(),
                    RowVersion = YitIdHelper.NextId(),
                    Name = Guid.NewGuid().ToString()
                }));
                dic.Add(BuildDictionaryParam(new
                {
                    CreateTime = DateTime.Now,
                    Id = YitIdHelper.NextId(),
                    RowVersion = YitIdHelper.NextId(),
                    Name = Guid.NewGuid().ToString()
                }));
                bar.Tick($" {i} of {totalTicks}");
            }
        }

        var result = new List<object>();
        foreach (var item in dic)
        {
            var obj = table.CreateInstance(item);
            result.Add(obj);
        }

        return result;
    }

    private void SingleCurd()
    {
        var table = freeSql.CodeFirst
            .DynamicEntity("TestFreeSqlEntity_low_code", new TableAttribute { Name = "free_sql_default_test" })
            .Extend(typeof(TestEntityBase))
            .Property("Name", typeof(string), new ColumnAttribute { StringLength = 50 })
            .Build();


        var inputList = PrepareTestData(table);

        var insert = freeSql.Insert<object>().AsType(table.Type).AppendData(inputList);
        var insertSql = insert.ToSql();
        Console.WriteLine(insertSql);
        insert.ExecuteAffrows();


        foreach (var item in inputList)
        {
            var dic = BuildDictionaryParam(item);
            dic["Name"] = DateTime.Now.ToLongTimeString();
            var obj = table.CreateInstance(dic);
            freeSql.Update<object>().AsType(table.Type)
                .SetSource(obj).ExecuteAffrows();
        }

        var select = freeSql.Select<object>().AsType(table.Type);
        var selectSql = select.ToSql();
        Console.WriteLine(selectSql);
        var list = select.ToList();


        Console.WriteLine(list.Count);
    }

    private void JoinQuery()
    {
    }

    private void SingleSpiltCurd()
    {
        var table = freeSql.CodeFirst
            .DynamicEntity("TestFreeSqlEntity_spilit_low_code",
                           new TableAttribute
                           {
                               Name = "free_sql_default_test_{yyyyMMdd}",
                               AsTable = "CreateTime=2020-12-14(1095,1 day)"
                           })
            .Extend(typeof(TestEntityBase))
            .Property("Name", typeof(string), new ColumnAttribute { StringLength = 50 })
            .Build();

        var baseTable = freeSql.CodeFirst.GetTableByEntity(typeof(UserEntity));
        var asTableImpl = freeSql.CodeFirst.GetTableByEntity(table.Type).AsTableImpl
            .SetTableName(0, "free_sql_default_test");
        //未设置时间条件时，只命中最新的 3个分表：
        freeSql.CodeFirst.GetTableByEntity(table.Type).AsTableImpl
            .SetDefaultAllTables(value => value.Take(2).ToArray());


        var inputList = PrepareTestData(table);

        var insert = freeSql.Insert<object>().AsType(table.Type).AppendData(inputList);
        var insertSql = insert.ToSql();
        Console.WriteLine(insertSql);
        insert.ExecuteAffrows();


        foreach (var item in inputList)
        {
            var dic = BuildDictionaryParam(item);
            dic["Name"] = DateTime.Now.ToLongTimeString();
            var obj = table.CreateInstance(dic);
            freeSql.Update<object>().AsType(table.Type)
                .SetSource(obj).ExecuteAffrows();
        }

        var select = freeSql.Select<object>().AsType(table.Type);
        var selectSql = select.ToSql();
        Console.WriteLine(selectSql);
        var list = select.ToList();


        Console.WriteLine(list.Count);
    }


    private void DynamicFilter() { }
}
